package com.bridgeintelligent.tag.engine.mvc.strategy;

import com.bridgeintelligent.tag.engine.api.DimInfo;
import com.bridgeintelligent.tag.engine.api.DimItemInfo;
import com.bridgeintelligent.tag.engine.api.IndexNameInfo;
import com.bridgeintelligent.tag.engine.api.rsp.MultiAnalysisAggregationResult;
import com.bridgeintelligent.tag.engine.es.model.AnalysisAggregationModel;
import com.bridgeintelligent.tag.engine.mvc.service.IGroupService;
import com.bridgeintelligent.tag.utils.FieldHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.aggregations.metrics.Max;
import org.elasticsearch.search.aggregations.metrics.Min;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Slf4j
public class XDateDefaultYTermDefault extends AbstractAnalysisTemple{

    public XDateDefaultYTermDefault(AnalysisAggregationModel model,  IGroupService groupService){
        super(model,groupService);
    }

    @Override
    public MultiAnalysisAggregationResult analysisHandler() throws IOException {
        AnalysisAggregationModel model = this.model;
        //获取索引信息
        IndexNameInfo indexInfo = this.getIndexInfo(model.getIndexId());
        //获取QueryBuilder
        QueryBuilder queryBuilder;
        if (FieldHandler.FALSE.equals(model.getTimeType())){
            queryBuilder = this.getQueryBuilder(this.model.getFilterGroup());
        }else{
            queryBuilder = this.getStaticQueryBuilder(this.model.getCustomerId());
        }
        //获取X字段的真实值
        String xDimId = this.getRealField(model.getField(),model.getDataDate(),model.getRelation());
        //获取X字段的分组间距
        DateHistogramInterval xInterval = this.getDateInterval(xDimId, queryBuilder,model.getIndexId());
        //获取Y字段的真实值
        String yDimId = this.getRealField(model.getYfield(),model.getDataDate(),model.getRelation());
        //封装SourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //封装X字段的聚合函数
        DateHistogramAggregationBuilder xDateHistogramAggregation = this.getDateHistogramAggregation(model.getField(), xDimId, xInterval);
        //封装y字段的聚合函数
        TermsAggregationBuilder yTermsAggregation = this.getTermAggregation(model.getYfield(), yDimId, model.getYDimInfo().getClassify());
        //封装y下的统计指标
        yTermsAggregation = (TermsAggregationBuilder)this.subAggregation(yTermsAggregation,model);
        xDateHistogramAggregation.subAggregation(yTermsAggregation);
        searchSourceBuilder.aggregation(xDateHistogramAggregation);
        searchSourceBuilder.query(queryBuilder).trackTotalHits(true).size(0);
        //封装searchRequest
        SearchRequest searchRequest = new SearchRequest(indexInfo.getDataDate()).source(searchSourceBuilder);

        return getResult(searchRequest,model,xInterval,model.getXDimInfo(),model.getYDimInfo());
    }

    public MultiAnalysisAggregationResult getResult(SearchRequest searchRequest,AnalysisAggregationModel model,DateHistogramInterval xInterval,DimInfo xDimInfo,DimInfo yDimInfo) throws IOException {

        SearchResponse searchResponse = this.search(searchRequest);
        //获取文档数
        long totalValue = searchResponse.getHits().getTotalHits().value;
        //获取X维度聚合
        Aggregations aggregations = searchResponse.getAggregations();
        Histogram histogram = aggregations.get("histogram_"+model.getField());
        List<MultiAnalysisAggregationResult.X> data = new ArrayList<>();
        for (Histogram.Bucket entry : histogram.getBuckets()) {
           //获取x维度下的title分组信息
            String xTitle = this.getDateTitle(entry.getKeyAsString(), xInterval);

            Terms terms = entry.getAggregations().get("group_"+model.getYfield());
            List<MultiAnalysisAggregationResult.Y> ys = new ArrayList<>();
            for (Terms.Bucket entry1: terms.getBuckets()) {

                //计算y维度的title分组信息,需要处理成中文
                String yTitle = Optional
                        .ofNullable(this.getDimItemInfo(model.getYfield(),entry1.getKeyAsString()))
                        .map(DimItemInfo::getDimItemName)
                        .orElse(entry1.getKeyAsString());
                if (StringUtils.equals("06",yDimInfo.getClassify())){
                    yTitle = this.joinStr(yTitle,entry1.getKeyAsString());
                }

                //封装y维度下的统计指标
                List<MultiAnalysisAggregationResult.Info> infos = new ArrayList<>();
                if (!CollectionUtils.isEmpty(model.getFields())){
                    model.getFields().forEach(e -> {
                        Max max = entry1.getAggregations().get("max_" + e);
                        Min min = entry1.getAggregations().get("min_" + e);
                        Avg avg = entry1.getAggregations().get("avg_" + e);
                        Sum sum = entry1.getAggregations().get("sum_" + e);
                        infos.add(MultiAnalysisAggregationResult.Info.of()
                                .setField(e)
                                .setMaxValue(realValue(max.getValueAsString()))
                                .setMinValue(realValue(min.getValueAsString()))
                                .setSumValue(realValue(sum.getValueAsString()))
                                .setAvgValue(realValue(avg.getValueAsString())));
                    });
                }
                //封装y维度聚合信息
                ys.add(MultiAnalysisAggregationResult.Y.of()
                        .setTitle(yTitle)
                        .setCount(entry1.getDocCount())
                        .setInfo(infos)
                        .setPercent(this.compute(entry1.getDocCount(),totalValue))
                );
            }

            //封装x维度聚合信息
            data.add(MultiAnalysisAggregationResult.X.of()
                        .setTitle(xTitle)
                        .setCount(entry.getDocCount())
                        .setPercent(this.compute(entry.getDocCount(),totalValue))
                        .setYs(ys)
            );
        }
        this.sortX(xDimInfo.getClassify(),data);
        //封装综合信息
        return MultiAnalysisAggregationResult.of()
                .setXDimId(xDimInfo.getDimId())
                .setXDimName(xDimInfo.getDimName())
                .setXClassify(xDimInfo.getClassify())
                .setYDimId(yDimInfo.getDimId())
                .setYDimName(yDimInfo.getDimName())
                .setYClassify(yDimInfo.getClassify())
                .setTotalCount(totalValue)
                .setData(data);

    }





}
